package com.yingsheng.bi.hks.basic.utils;


import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * Java IO流工具类
 *
 * @author root
 */
@Slf4j
public class IOUtils {
    public static int BUFFER_SIZE = 8192;


    /**
     * 通过文件路径读取文件
     *
     * @param filePath 文件全路径
     * @return 件内容字节数组
     */
    public static byte[] read(String filePath) {
        try {
            return read(Files.newInputStream(Paths.get(filePath)));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 通过文件流读取文件
     *
     * @param in 读取的文件流
     * @return 文件内容字节数组
     */
    public static byte[] read(InputStream in) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            byte[] buf = new byte[BUFFER_SIZE];
            while (true) {
                int len = in.read(buf);
                if (len == -1) {
                    break;
                }
                os.write(buf, 0, len);
            }
        } catch (IOException var4) {
            log.warn(warn(var4));
        }
        return os.toByteArray();
    }

    /**
     * 读取文件全部内容并转换为字符串形式返回
     *
     * @param in 读取的文件流
     * @return 文件内容字节数组
     */
    public static String read2String(InputStream in, String encoding) {
        byte[] buffer = read(in);
        try {
            return new String(buffer, encoding);
        } catch (UnsupportedEncodingException var5) {
            return new String(buffer);
        }
    }

    /**
     * 按行读取文件
     *
     * @param in       读取的文件流
     * @param encoding 文件字符集
     * @return 读取行内容
     */
    public static String readLine(InputStream in, String encoding) {
        try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            int c = in.read();
            if (c == -1) {
                return null;
            } else {
                for (; c != -1 && c != 10; c = in.read()) {
                    if (c != 13) {
                        bout.write(c);
                    }
                }

                return bout.toString(encoding);
            }
        } catch (IOException var4) {
            log.warn(warn(var4, encoding));
            return null;
        }
    }

    /**
     * 按行读取文件
     *
     * @param in       读取的文件流
     * @param encoding 文件字符集
     * @return 文件行内容列表
     */
    public static List<String> readLines(InputStream in, String encoding) {
        List<String> result = new ArrayList<>();
        for (String line = readLine(in, encoding); line != null; line = readLine(in, encoding)) {
            result.add(line);
        }
        return result;
    }

    public static String checkFilePath(String filePath) {
        if (filePath == null || filePath.isEmpty()) {
            return filePath;
        }
        char lastChar = filePath.charAt(filePath.length() - 1);
        return lastChar != File.separatorChar ? filePath + File.separator : filePath;
    }

    /**
     * 文件写入
     *
     * @param fileFullPath 文件的全路径
     * @param content      文件的内容
     * @return 文件写入结果 成功或者失败
     */
    public static boolean write(String fileFullPath, byte[] content) {
        return write(fileFullPath, new ByteArrayInputStream(content), false);
    }

    /**
     * 文件写入
     *
     * @param fileFullPath 文件的全路径
     * @param in           文件流
     * @return 文件写入结果 成功或者失败
     */
    public static boolean write(String fileFullPath, InputStream in) {
        return write(fileFullPath, in, false);
    }

    /**
     * 文件写入
     *
     * @param fileFullPath 文件的全路径
     * @param in           文件流
     * @param backup       旧备份标识 是与否
     * @return 文件写入结果 成功或者失败
     */
    public static boolean write(String fileFullPath, InputStream in, boolean backup) {
        FileOutputStream out = null;
        try {
            File file = new File(fileFullPath);
            if (!file.exists()) {
                File dir = file.getParentFile();
                if (!dir.exists()) {
                    boolean mkdir = dir.mkdirs();
                }
                boolean createNewFile = file.createNewFile();
            } else if (backup) {
                File dir = new File(fileFullPath + "_" + DateUtils.currentCompactDateTime());
                file.renameTo(dir);
            }
            out = new FileOutputStream(file, false);
            copy(in, out);
            out.flush();
            return true;
        } catch (Exception var10) {
            log.warn(warn(var10, fileFullPath));
        } finally {
            close(out);
        }
        return false;
    }

    /**
     * 删除文件
     *
     * @param file
     * @return 删除的结果 成功或失败
     */
    public static boolean delete(File file) {
        if (file != null && file.exists()) {
            if (file.isFile()) {
                return file.delete();
            } else if (file.isDirectory()) {
                File[] subFiles = file.listFiles();
                if (subFiles != null) {
                    for (File subFile : subFiles) {
                        if (!delete(subFile)) { // 递归删除文件和子目录
                            return false;
                        }
                    }
                }
                return file.delete();
            }
        }
        return false;
    }

    public static boolean close(Collection<Closeable> iss) {
        boolean flag = true;
        if (iss != null) {
            for (Closeable is : iss) {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException var5) {
                        log.info(warn(var5));
                        flag = false;
                    }
                }
            }
        }
        return flag;
    }

    public static boolean close(Closeable... iss) {
        return close(Arrays.asList(iss));
    }

    public static void copy(InputStream is, OutputStream os) throws IOException {
        byte[] buf = new byte[BUFFER_SIZE];
        while (true) {
            int len = is.read(buf);
            if (len == -1) {
                return;
            }
            os.write(buf, 0, len);
        }
    }

    static String warn(Exception e, String... names) {
        StringBuilder sb = new StringBuilder(e.toString());
        for (String name : names) {
            sb.append(':').append(name);
        }
        return sb.toString();
    }
}

